package com.joe.learn.leetcode;

/**
 * 给出两个 非空 的链表用来表示两个非负的整数。其中，它们各自的位数是按照 逆序 的方式存储的，并且它们的每个节点只能存储 一位 数字。
 * <p>
 * 如果，我们将这两个数相加起来，则会返回一个新的链表来表示它们的和。
 * <p>
 * 您可以假设除了数字 0 之外，这两个数都不会以 0 开头。
 * <p>
 * 示例：
 * <p>
 * 输入：(2 -> 4 -> 3) + (5 -> 6 -> 4)
 * 输出：7 -> 0 -> 8
 * 原因：342 + 465 = 807
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/add-two-numbers
 */
public class AddTwoNumber {

    public static void main(String[] args) {
        ListNode l1 = new ListNode(2);
        l1.next = new ListNode(4);
        l1.next.next = new ListNode(3);

        ListNode l2 = new ListNode(5);
        l2.next = new ListNode(6);
        l2.next.next = new ListNode(4);

        ListNode val = addTwoNumbers(l1, l2);
        System.out.println(val);
    }

    /**
     * 面向对象的理解方式会影响对指针的理解，而链表的思想就是需要思考指针的位置。
     *
     * @param l1
     * @param l2
     * @return
     */
    public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode root = new ListNode(0);
        //声明一个节点，并指向当前根节点
        ListNode cursor = root;
        int carry = 0;

        while (l1 != null || l2 != null || carry != 0) {
            int sumVal = carry;

            sumVal += l1 == null ? 0 : l1.val;
            sumVal += l2 == null ? 0 : l2.val;

            carry = sumVal / 10;

            ListNode sumNode = new ListNode(sumVal % 10);

            //先将sumNode赋值给当前节点的next，然后再将节点指向下一个。
            cursor.next = sumNode;
            // TODO 关于等号的理解，在基本类型中，表示将变量进栈，并且将变量的内存区域赋值。而对于引用类型来说，则是地址的传递。如 <code>String a= "Hello";<code> a的值是 "Hello"字符串对象的地址。
            cursor = cursor.next; // 也可以写为 cursor = sumNode  将 cursor 的指针指向sumNode节点。


            if (l1 != null) l1 = l1.next;
            if (l2 != null) l2 = l2.next;
        }

        return root.next;
    }
}


class ListNode {

    int val;

    ListNode next;

    ListNode(int x) {
        val = x;
    }

}